import tempfile
import uuid
from enum import IntEnum
from pathlib import Path

from yt_dlp import YoutubeDL


class SourceUrlDomainType(IntEnum):
    """
    源url对应的视频网站类型
    """
    YOUTUBE = 0
    BILIBILI = 1

class TargetVideoFileClarity(IntEnum):
    """
    要下载的视频文件的目标清晰度
    """
    WORST = 0
    """
    最低清晰度
    """

    MEDIUM = 1
    """
    中等清晰度（1080p~720p）
    """

    BEST = 2
    """
    最高清晰度
    """


def parse_source_url_domain_type(source_url: str) -> SourceUrlDomainType:
    if source_url.startswith("https://www.youtube.com") or source_url.find("youtube.com") != -1:
        return SourceUrlDomainType.YOUTUBE
    elif source_url.startswith("https://www.bilibili.com") or source_url.find("bilibili.com") != -1:
        return SourceUrlDomainType.BILIBILI
    else:
        raise ValueError("unable to parse source url domain type")

def download_page_video(source_url: str, target_clarity: TargetVideoFileClarity = TargetVideoFileClarity.MEDIUM):
    """
    从指定的视频页面中下载视频文件
    :param target_clarity:
    :param source_url:
    :return:
    """

    type = parse_source_url_domain_type(source_url)
    if type == SourceUrlDomainType.YOUTUBE:
        return download_from_youtube(source_url, target_clarity)
    else:
        raise ValueError("unable to parse source url domain type")

def download_from_youtube(source_url: str, target_clarity: TargetVideoFileClarity = TargetVideoFileClarity.MEDIUM) -> Path:
    download_path = Path(tempfile.gettempdir()) / str(uuid.uuid4())
    ydl_opts = {
        'outtmpl': str(download_path / 'f%(format_id)s.%(ext)s'),
        'cookiesfrombrowser': ('firefox',) # 这里要做兼容处理
    }

    _config_ytdlp_target_clarity(ydl_opts, target_clarity)

    exact_file_name = ""
    with YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(source_url, download=False)
        exact_file_name = ydl.prepare_filename(info)

        error_code = ydl.download(source_url)

    if error_code != 0:
        raise RuntimeError("download youtube video failed")

    exact_file_path = Path(exact_file_name)
    if not exact_file_path.is_file():
        raise RuntimeError("unable to find downloaded youtube video")

    return exact_file_path
    # 以ytb的title来命名的的文件容易夹杂非url safe的字符，这里处理一下
    # if quote(exact_file_path.name) != exact_file_path.name:
    #     return exact_file_path.rename(exact_file_path.parent / quote(exact_file_path.name))
    # else:
    #     return exact_file_path


def _config_ytdlp_target_clarity(ydl_opts: dict, clarity: TargetVideoFileClarity) -> str:
    if clarity == TargetVideoFileClarity.WORST:
        ydl_opts['format_sort'] = ["res:360"]
    elif clarity == TargetVideoFileClarity.MEDIUM:
        ydl_opts['format_sort'] = ["res:1080"]
    # 默认yt-dlp就是取最高清晰度的，所以BEST枚举不用处理

